// None
// None
// None
// None
// None
// None
// None
// None
// None
// None
// 特此向任何获得副本的人免费授予许可
// 本软件和相关文档文件（“软件”）的
// 在软件中不受限制，包括但不限于权利
// 使用、复制、修改、合并、发布、分发、再许可和/或销售
// 软件的副本，并允许向其提供软件的人员
// 按照以下条件提供：
// None
// 上述版权声明和本许可声明应包含在
// 软件的所有副本或主要部分。
// None
// 本软件按“原样”提供，无任何形式的明示或明示担保
// 默示，包括但不限于适销性保证，
// 适用于特定目的和非侵权。在任何情况下
// 作者或版权持有人应承担任何索赔、损害或其他责任
// 无论是在合同诉讼、侵权诉讼或其他诉讼中，由以下原因引起的责任：，
// 与本软件有关或与本软件的使用或其他交易有关
// 软件。

package riscv

import "cmd/internal/obj"

// go:generate go run../stringer.go-i$GOFILE-o anames.go-p riscv

const (
	// 基址寄存器编号。
	REG_X0 = obj.RBaseRISCV + iota
	REG_X1
	REG_X2
	REG_X3
	REG_X4
	REG_X5
	REG_X6
	REG_X7
	REG_X8
	REG_X9
	REG_X10
	REG_X11
	REG_X12
	REG_X13
	REG_X14
	REG_X15
	REG_X16
	REG_X17
	REG_X18
	REG_X19
	REG_X20
	REG_X21
	REG_X22
	REG_X23
	REG_X24
	REG_X25
	REG_X26
	REG_X27
	REG_X28
	REG_X29
	REG_X30
	REG_X31

	// FP寄存器编号。
	REG_F0
	REG_F1
	REG_F2
	REG_F3
	REG_F4
	REG_F5
	REG_F6
	REG_F7
	REG_F8
	REG_F9
	REG_F10
	REG_F11
	REG_F12
	REG_F13
	REG_F14
	REG_F15
	REG_F16
	REG_F17
	REG_F18
	REG_F19
	REG_F20
	REG_F21
	REG_F22
	REG_F23
	REG_F24
	REG_F25
	REG_F26
	REG_F27
	REG_F28
	REG_F29
	REG_F30
	REG_F31

	// 这标志着寄存器编号的结束。
	REG_END

	// 将普通登记册重新分配给ABI名称。
	REG_ZERO = REG_X0
	REG_RA   = REG_X1 // aka REG_LR
	REG_SP   = REG_X2
	REG_GP   = REG_X3 // 又名REG_SB
	REG_TP   = REG_X4
	REG_T0   = REG_X5
	REG_T1   = REG_X6
	REG_T2   = REG_X7
	REG_S0   = REG_X8
	REG_S1   = REG_X9
	REG_A0   = REG_X10
	REG_A1   = REG_X11
	REG_A2   = REG_X12
	REG_A3   = REG_X13
	REG_A4   = REG_X14
	REG_A5   = REG_X15
	REG_A6   = REG_X16
	REG_A7   = REG_X17
	REG_S2   = REG_X18
	REG_S3   = REG_X19
	REG_S4   = REG_X20 // 又名REG_CTXT
	REG_S5   = REG_X21
	REG_S6   = REG_X22
	REG_S7   = REG_X23
	REG_S8   = REG_X24
	REG_S9   = REG_X25
	REG_S10  = REG_X26
	REG_S11  = REG_X27 // 阿卡雷格
	REG_T3   = REG_X28
	REG_T4   = REG_X29
	REG_T5   = REG_X30
	REG_T6   = REG_X31 // aka REG_TMP

	// 转到运行时注册表名。
	REG_G    = REG_S11 // G指针。
	REG_CTXT = REG_S4  // 闭包的上下文。
	REG_LR   = REG_RA  // 链接寄存器。
	REG_TMP  = REG_T6  // 保留供汇编程序使用。

	// 浮点寄存器的ABI名称。
	REG_FT0  = REG_F0
	REG_FT1  = REG_F1
	REG_FT2  = REG_F2
	REG_FT3  = REG_F3
	REG_FT4  = REG_F4
	REG_FT5  = REG_F5
	REG_FT6  = REG_F6
	REG_FT7  = REG_F7
	REG_FS0  = REG_F8
	REG_FS1  = REG_F9
	REG_FA0  = REG_F10
	REG_FA1  = REG_F11
	REG_FA2  = REG_F12
	REG_FA3  = REG_F13
	REG_FA4  = REG_F14
	REG_FA5  = REG_F15
	REG_FA6  = REG_F16
	REG_FA7  = REG_F17
	REG_FS2  = REG_F18
	REG_FS3  = REG_F19
	REG_FS4  = REG_F20
	REG_FS5  = REG_F21
	REG_FS6  = REG_F22
	REG_FS7  = REG_F23
	REG_FS8  = REG_F24
	REG_FS9  = REG_F25
	REG_FS10 = REG_F26
	REG_FS11 = REG_F27
	REG_FT8  = REG_F28
	REG_FT9  = REG_F29
	REG_FT10 = REG_F30
	REG_FT11 = REG_F31

	// SSA编译器生成的名称。
	REGSP = REG_SP
	REGG  = REG_G
)

// https:
var RISCV64DWARFRegisters = map[int16]int16{
	// 整数寄存器。
	REG_X0:  0,
	REG_X1:  1,
	REG_X2:  2,
	REG_X3:  3,
	REG_X4:  4,
	REG_X5:  5,
	REG_X6:  6,
	REG_X7:  7,
	REG_X8:  8,
	REG_X9:  9,
	REG_X10: 10,
	REG_X11: 11,
	REG_X12: 12,
	REG_X13: 13,
	REG_X14: 14,
	REG_X15: 15,
	REG_X16: 16,
	REG_X17: 17,
	REG_X18: 18,
	REG_X19: 19,
	REG_X20: 20,
	REG_X21: 21,
	REG_X22: 22,
	REG_X23: 23,
	REG_X24: 24,
	REG_X25: 25,
	REG_X26: 26,
	REG_X27: 27,
	REG_X28: 28,
	REG_X29: 29,
	REG_X30: 30,
	REG_X31: 31,

	// 浮点寄存器。
	REG_F0:  32,
	REG_F1:  33,
	REG_F2:  34,
	REG_F3:  35,
	REG_F4:  36,
	REG_F5:  37,
	REG_F6:  38,
	REG_F7:  39,
	REG_F8:  40,
	REG_F9:  41,
	REG_F10: 42,
	REG_F11: 43,
	REG_F12: 44,
	REG_F13: 45,
	REG_F14: 46,
	REG_F15: 47,
	REG_F16: 48,
	REG_F17: 49,
	REG_F18: 50,
	REG_F19: 51,
	REG_F20: 52,
	REG_F21: 53,
	REG_F22: 54,
	REG_F23: 55,
	REG_F24: 56,
	REG_F25: 57,
	REG_F26: 58,
	REG_F27: 59,
	REG_F28: 60,
	REG_F29: 61,
	REG_F30: 62,
	REG_F31: 63,
}

// 程序标记标志。
const (
	// AUIPC指令上设置了NEED_PCREL_ITYPE_RELOC以指示
	// 这是AUIPC+I型对中第一条需要
	// R_RISCV_PCREL_ITYPE重新定位。
	NEED_PCREL_ITYPE_RELOC = 1 << 0

	// AUIPC指令上设置了NEED_PCREL_STYPE_RELOC以指示
	// 这是AUIPC+S型对中第一条需要
	// R_RISCV_PCREL_STYPE搬迁。
	NEED_PCREL_STYPE_RELOC = 1 << 1
)

// RISC-V助记符，定义见“操作码”和“操作码伪”文件
// 发件人：
// None
// https:
// None
// 以及一些仅在汇编程序中使用的伪助记符（如MOV）。
// None
// 另请参见“RISC-V指令集手册”，网址：
// None
// https:
// None
// 如果修改此表，则必须运行“go generate”以重新生成anames.go！
const (
	// 非特权ISA（文件版本20190608）

	// 2.4：整数计算指令
	AADDI = obj.ABaseRISCV + obj.A_ARCHSPECIFIC + iota
	ASLTI
	ASLTIU
	AANDI
	AORI
	AXORI
	ASLLI
	ASRLI
	ASRAI
	ALUI
	AAUIPC
	AADD
	ASLT
	ASLTU
	AAND
	AOR
	AXOR
	ASLL
	ASRL
	ASUB
	ASRA

	// RV32和RV64之间的SLL/SRL/SRA指令略有不同，
	// 因此，RV32特定版本有伪操作码。
	ASLLIRV32
	ASRLIRV32
	ASRAIRV32

	// 2.5：控制转移指令
	AJAL
	AJALR
	ABEQ
	ABNE
	ABLT
	ABLTU
	ABGE
	ABGEU

	// 2.6：装载和储存说明
	ALW
	ALWU
	ALH
	ALHU
	ALB
	ALBU
	ASW
	ASH
	ASB

	// 2.7：内存订购说明
	AFENCE
	AFENCEI
	AFENCETSO

	// 5.2：整数计算指令（RV64I）
	AADDIW
	ASLLIW
	ASRLIW
	ASRAIW
	AADDW
	ASLLW
	ASRLW
	ASUBW
	ASRAW

	// 5.3：装载和储存说明（RV64I）
	ALD
	ASD

	// 7.1：乘法运算
	AMUL
	AMULH
	AMULHU
	AMULHSU
	AMULW
	ADIV
	ADIVU
	AREM
	AREMU
	ADIVW
	ADIVUW
	AREMW
	AREMUW

	// 8.2：加载保留/存储条件指令
	ALRD
	ASCD
	ALRW
	ASCW

	// 8.3：原子存储器操作
	AAMOSWAPD
	AAMOADDD
	AAMOANDD
	AAMOORD
	AAMOXORD
	AAMOMAXD
	AAMOMAXUD
	AAMOMIND
	AAMOMINUD
	AAMOSWAPW
	AAMOADDW
	AAMOANDW
	AAMOORW
	AAMOXORW
	AAMOMAXW
	AAMOMAXUW
	AAMOMINW
	AAMOMINUW

	// 10.1：基本计数器和计时器
	ARDCYCLE
	ARDCYCLEH
	ARDTIME
	ARDTIMEH
	ARDINSTRET
	ARDINSTRETH

	// 11.2：浮点控制和状态寄存器
	AFRCSR
	AFSCSR
	AFRRM
	AFSRM
	AFRFLAGS
	AFSFLAGS
	AFSRMI
	AFSFLAGSI

	// 11.5：单精度加载和存储说明
	AFLW
	AFSW

	// 11.6：单精度浮点计算指令
	AFADDS
	AFSUBS
	AFMULS
	AFDIVS
	AFMINS
	AFMAXS
	AFSQRTS
	AFMADDS
	AFMSUBS
	AFNMADDS
	AFNMSUBS

	// 11.7：单精度浮点转换和移动指令
	AFCVTWS
	AFCVTLS
	AFCVTSW
	AFCVTSL
	AFCVTWUS
	AFCVTLUS
	AFCVTSWU
	AFCVTSLU
	AFSGNJS
	AFSGNJNS
	AFSGNJXS
	AFMVXS
	AFMVSX
	AFMVXW
	AFMVWX

	// 11.8：单精度浮点比较指令
	AFEQS
	AFLTS
	AFLES

	// 11.9：单精度浮点分类指令
	AFCLASSS

	// 12.3：双精度加载和存储说明
	AFLD
	AFSD

	// 12.4：双精度浮点计算指令
	AFADDD
	AFSUBD
	AFMULD
	AFDIVD
	AFMIND
	AFMAXD
	AFSQRTD
	AFMADDD
	AFMSUBD
	AFNMADDD
	AFNMSUBD

	// 12.5：双精度浮点转换和移动指令
	AFCVTWD
	AFCVTLD
	AFCVTDW
	AFCVTDL
	AFCVTWUD
	AFCVTLUD
	AFCVTDWU
	AFCVTDLU
	AFCVTSD
	AFCVTDS
	AFSGNJD
	AFSGNJND
	AFSGNJXD
	AFMVXD
	AFMVDX

	// 12.6：双精度浮点比较指令
	AFEQD
	AFLTD
	AFLED

	// 12.7：双精度浮点分类指令
	AFCLASSD

	// 13.1四精度加载和存储说明
	AFLQ
	AFSQ

	// 13.2：四精度计算指令
	AFADDQ
	AFSUBQ
	AFMULQ
	AFDIVQ
	AFMINQ
	AFMAXQ
	AFSQRTQ
	AFMADDQ
	AFMSUBQ
	AFNMADDQ
	AFNMSUBQ

	// 13.3四精度转换和移动指令
	AFCVTWQ
	AFCVTLQ
	AFCVTSQ
	AFCVTDQ
	AFCVTQW
	AFCVTQL
	AFCVTQS
	AFCVTQD
	AFCVTWUQ
	AFCVTLUQ
	AFCVTQWU
	AFCVTQLU
	AFSGNJQ
	AFSGNJNQ
	AFSGNJXQ
	AFMVXQ
	AFMVQX

	// 13.4四精度浮点比较指令
	AFEQQ
	AFLEQ
	AFLTQ

	// 13.5四精度浮点分类指令
	AFCLASSQ

	// 特权ISA（MSU批准的20190608版Priv）

	// 3.1.9：访问CSR的说明
	ACSRRW
	ACSRRS
	ACSRRC
	ACSRRWI
	ACSRRSI
	ACSRRCI

	// 3.2.1：环境调用和断点
	AECALL
	ASCALL
	AEBREAK
	ASBREAK

	// 3.2.2：陷阱返回说明
	AMRET
	ASRET
	AURET
	ADRET

	// 3.2.3：等待中断
	AWFI

	// 4.2.1：主管内存管理围栏说明
	ASFENCEVMA

	// 虚拟机监控程序内存管理指令
	AHFENCEGVMA
	AHFENCEVVMA

	// 逃生舱。插入单个32位字。
	AWORD

	// 伪指令。这些被汇编程序翻译成其他语言
	// 指令，基于它们的操作数。
	ABEQZ
	ABGEZ
	ABGT
	ABGTU
	ABGTZ
	ABLE
	ABLEU
	ABLEZ
	ABLTZ
	ABNEZ
	AFNEGD
	AFNEGS
	AFNED
	AFNES
	AMOV
	AMOVB
	AMOVBU
	AMOVF
	AMOVD
	AMOVH
	AMOVHU
	AMOVW
	AMOVWU
	ANEG
	ANEGW
	ANOT
	ASEQZ
	ASNEZ

	// 结束标记
	ALAST
)

// 所有写入参数的一元指令（与读取相反）
// 从他们那里）到这里。程序集解析器使用此信息来填充
// 它的AST在语义上是合理的。
// None
// 此处未列出的任何指令均假定为非一元指令或可读指令
// 从它的论点来看。
var unaryDst = map[obj.As]bool{
	ARDCYCLE:    true,
	ARDCYCLEH:   true,
	ARDTIME:     true,
	ARDTIMEH:    true,
	ARDINSTRET:  true,
	ARDINSTRETH: true,
}

// 指令编码掩码。
const (
	// ITypeImmMask是一个仅包含
	// I型指令。
	ITypeImmMask = 0xfff00000

	// STypeImmMask是一种仅包含当前部分的掩码
	// S型指令。
	STypeImmMask = 0xfe000f80

	// UTypeImmMask是一个仅包含
	// U型指示。
	UTypeImmMask = 0xfffff000

	// UJTypeImmMask是一个仅包含
	// UJ类型说明。
	UJTypeImmMask = UTypeImmMask
)
